package _case

import (
	"fmt"
	"time"
)

// 携程间通信
func Communication() {
	//可读可写
	ch := make(chan int)
	go goCommunication1(ch)
	go goCommunication2(ch)
}

// 只写通道
func goCommunication1(ch chan<- int) {
	for i := 0; i < 10; i++ {
		ch <- i
		fmt.Println("进入通道:", i)
	}
}

// 只读通道
func goCommunication2(ch <-chan int) {
	for i := range ch {
		fmt.Println("输出通道：", i)
	}
}

// 并发场景下的同步机制
func ConcurrentSync() {
	//带缓冲的通道
	ch := make(chan int, 10)

	go func() {
		for i := 0; i < 10; i++ {
			ch <- i
		}
	}()

	go func() {
		for i := 0; i < 10; i++ {
			ch <- i
		}
	}()

	go func() {
		for i := range ch {
			fmt.Println(i)
		}
	}()
}

func NoticeAndMultiplexing() {
	ch1 := make(chan int)
	ch2 := make(chan string)
	ch3 := make(chan struct{})
	go noticeAndMultiplexing1(ch1)
	go noticeAndMultiplexing2(ch2)
	go noticeAndMultiplexing3(ch1, ch2, ch3)
	time.Sleep(3 * time.Second)
	//向通道发送一个nil值，触发关闭通道
	close(ch3)
}

func noticeAndMultiplexing1(ch chan<- int) {
	for i := 0; i < 10; i++ {
		ch <- i
	}
}

func noticeAndMultiplexing2(ch chan<- string) {
	for i := 0; i < 10; i++ {
		ch <- fmt.Sprintf("数字：%d", i)
	}
}

// select 作为一个整体阻塞，任意一个channel准备好，就继续执行
func noticeAndMultiplexing3(ch1 <-chan int, ch2 <-chan string, done <-chan struct{}) {
	i := 0
	for {
		select {
		case i := <-ch1:
			fmt.Println(i)
		case str := <-ch2:
			fmt.Println(str)
		case <-done:
			fmt.Println("进程结束退出")
			return
		}
		i++
		fmt.Println("计数器：", i)
	}
}
